/**
 * @file mainwindow.cpp
 * @brief  control panel of the car
 * 
 * Copyright (C) 2014 JakeYang <add358@gmail.com>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork/QUdpSocket>
#include <QProcess>
#include <QDebug>
#include <QTimer>
#include "common.h"

#define START_MONITOR_TEXT                "开始监控"
#define STOP_MONITOR_TEXT                 "停止监控"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_udpSocket(NULL),
    process(new QProcess(this)),
    direction_flag(STOP)
{
    ui->setupUi(this);
    ui->label_car->setPixmap(QPixmap(":/images/car.png"));
    ui->pushButton_sure->setText(START_MONITOR_TEXT);
    setComponentsDisable(true);
}

MainWindow::~MainWindow()
{
    delete process;
    delete ui;
}

void MainWindow::keyPressEvent(QKeyEvent *e)
{
    qDebug()<<"Key Press"<<e->key();
    if (ui->pushButton_sure->text() == START_MONITOR_TEXT) {
        return;
    }

    switch (e->key()) {
    case Qt::Key_Up:
        if (FORWARD != direction_flag) {
            on_pushButton_forward_clicked();
            direction_flag = FORWARD;
        }
        break;
    case Qt::Key_Down:
        if (BACKWARD != direction_flag) {
            on_pushButton_backward_clicked();
            direction_flag = BACKWARD;
        }
        break;
    case Qt::Key_Right:
        if (FORWARD == direction_flag) {
            on_pushButton_turnRight_clicked();
        } else if (BACKWARD == direction_flag) {
            on_pushButton_turnBackRight_clicked();
        }
        break;
    case Qt::Key_Left:
        if (FORWARD == direction_flag) {
            on_pushButton_turnLeft_clicked();
        } else if (BACKWARD == direction_flag) {
            on_pushButton_turnBackLeft_clicked();
        }
        break;
    default:
        break;
    }
    QWidget::keyPressEvent(e);
}

void MainWindow::keyReleaseEvent(QKeyEvent *e)
{
    qDebug()<<"Key Release"<<e->key();
    if (ui->pushButton_sure->text() == START_MONITOR_TEXT) {
        return;
    }
    switch (e->key()) {
    case Qt::Key_Up:
    case Qt::Key_Down:
        on_pushButton_stop_clicked();
        direction_flag = STOP;
        break;
    case Qt::Key_Right:
    case Qt::Key_Left:
        if (FORWARD == direction_flag) {
            on_pushButton_forward_clicked();
        } else if (BACKWARD == direction_flag) {
            on_pushButton_backward_clicked();
        }
        break;
    default:
        break;
    }
    QWidget::keyReleaseEvent(e);
}

void MainWindow::setComponentsDisable(bool flag)
{
    ui->lineEdit_ip->setDisabled(!flag);
    ui->lineEdit_port->setDisabled(!flag);
    ui->pushButton_backward->setDisabled(flag);
    ui->pushButton_forward->setDisabled(flag);
    ui->pushButton_stop->setDisabled(flag);
    ui->pushButton_turnRight->setDisabled(flag);
    ui->pushButton_turnLeft->setDisabled(flag);
    ui->pushButton_turnBackRight->setDisabled(flag);
    ui->pushButton_turnBackLeft->setDisabled(flag);
}

void MainWindow::udp_recv()
{
    while (m_udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(m_udpSocket->pendingDatagramSize());
        m_udpSocket->readDatagram(datagram.data(), datagram.size());
        qDebug()<<datagram;
    }
}

void MainWindow::on_pushButton_sure_clicked()
{
    if (ui->pushButton_sure->text() == START_MONITOR_TEXT) {
        m_udpSocket = new QUdpSocket();
        connect( m_udpSocket, SIGNAL(readyRead()), this,  SLOT(udp_recv()) );

        setComponentsDisable(false);
        m_serverAddr.setAddress(ui->lineEdit_ip->text());
        m_serverPort = ui->lineEdit_port->text().toUShort();
        ui->pushButton_sure->setText(STOP_MONITOR_TEXT);

        ui->widget_video->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
        ui->widget_video->setAttribute(Qt::WA_OpaquePaintEvent);
        ui->widget_video->setMinimumSize(320,240);
        QStringList args;
        ui->widget_video->setVisible(true);
        args << "-wid" << QString::number(ui->widget_video->winId());
        args << "-demuxer";
        args << "rawvideo";
        args << "-rawvideo";
        args << "w=320:h=240:format=yuy2";
        args << "capture_file.yuv";
        args << "-loop"<<"0";
        process->setProcessChannelMode(QProcess::MergedChannels);
        process->start("mplayer", args);

        qDebug()<<ui->lineEdit_ip->text()<<"  "<<ui->lineEdit_port->text();
 } else {
        process->close();
        ui->widget_video->setVisible(false);
        setComponentsDisable(true);
        ui->pushButton_sure->setText(START_MONITOR_TEXT);
        disconnect( m_udpSocket, SIGNAL(readyRead()), this, SLOT(udp_recv()) );
        delete m_udpSocket;
        m_udpSocket = NULL;
    }
}

void MainWindow::on_pushButton_forward_clicked()
{
    m_udpSocket->writeDatagram(CAR_FORWARD, ::strlen(CAR_FORWARD), m_serverAddr,  m_serverPort);
}

void MainWindow::on_pushButton_backward_clicked()
{
    m_udpSocket->writeDatagram(CAR_BACKWARD, ::strlen(CAR_BACKWARD), m_serverAddr,  m_serverPort);
}

void MainWindow::on_pushButton_stop_clicked()
{
    m_udpSocket->writeDatagram(CAR_STOP, ::strlen(CAR_STOP), m_serverAddr,  m_serverPort);
}

void MainWindow::on_pushButton_turnLeft_clicked()
{
    m_udpSocket->writeDatagram(CAR_TURN_LEFT, ::strlen(CAR_TURN_LEFT), m_serverAddr, m_serverPort);
}

void MainWindow::on_pushButton_turnRight_clicked()
{
    m_udpSocket->writeDatagram(CAR_TURN_RIGHT, ::strlen(CAR_TURN_RIGHT), m_serverAddr, m_serverPort);
}

void MainWindow::on_pushButton_turnBackLeft_clicked()
{
    m_udpSocket->writeDatagram(CAR_TURN_BACKLEFT, ::strlen(CAR_TURN_BACKLEFT), m_serverAddr, m_serverPort);
}

void MainWindow::on_pushButton_turnBackRight_clicked()
{
    m_udpSocket->writeDatagram(CAR_TURN_BACKRIGHT, ::strlen(CAR_TURN_BACKRIGHT), m_serverAddr, m_serverPort);
}
